Draft: Add JSRPC passthroughs for delete and head on R2 bucket - #7092
Draft: Add JSRPC passthroughs for delete and head on R2 bucket#7092Carolx715 wants to merge 2 commits into
Conversation
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
| $pythonSnapshotRelease; | ||
| # Enables Python Workers using Pyodide 314.0.5. | ||
| r2BindingsJsrpc @187 :Bool | ||
| $compatEnableFlag("r2_bindings_jsrpc") |
There was a problem hiding this comment.
| $compatEnableFlag("r2_bindings_jsrpc") | |
| $compatEnableFlag("r2_binding_jsrpc") |
| } | ||
| traceContext.setTag("cloudflare.r2.request.key"_kjc, key.asPtr()); | ||
|
|
||
| auto rpcProp = getRpcMethod(js, "head"_kj); |
There was a problem hiding this comment.
The general approach LGTM here. I just have some structural suggestions.
They will all have to perform:
Ref
-> wrap as JS callable
-> assert unwrap as jsg::Function<jsg::Value(...)>
-> call with C++ args
-> normalize/unwrap RPC result
So I'd suggest pulling this out into a helper e.g.
template <typename Result, typename... Args>
jsg::Promise<Result> R2Bucket::callRpcMethod(jsg::Lock& js,
kj::StringPtr methodName,
const jsg::TypeHandler<jsg::Ref<JsRpcProperty>>& rpcPropHandler,
const jsg::TypeHandler<jsg::Function<jsg::Value(Args...)>>& fnHandler,
const jsg::TypeHandler<Result>& resultHandler,
Args&&... args) {
auto rpcProp = KJ_ASSERT_NONNULL(getRpcMethod(js, methodName));
auto wrappedProp = rpcPropHandler.wrap(js, kj::mv(rpcProp));
auto fn = KJ_ASSERT_NONNULL(fnHandler.tryUnwrap(js, wrappedProp));
auto rpcProm = fn(js, kj::fwd<Args>(args)...);
return normalizeRpcPromise(js, kj::mv(rpcProm), resultHandler);
}
Note that I've changed two JSG_REQUIRE_NONNULLs to KJ_ASSERT_NONNULLs because they are internal invariants that we are asserting, not part of the user API contract.
Then the impl of headRpc becomes simply:
// Set request trace context.
return callRpcMethod<kj::Maybe<HeadResultRpc>>(js, "head"_kj, rpcPropHandler, headFnHandler,
headResultHandler, kj::mv(key))
.then(js, [](jsg::Lock& js, kj::Maybe<HeadResultRpc> rpcResult) {
// Set response trace context.
// Parse response into `HeadResult`.
});
Also, to go a step further, I would probably prefer we re-use all the common tracing logic that is shared between the HTTP impl and JSRPC impl. The HTTP and JSRPC variants of each R2 binding method could just forward to a common method (e.g. headImpl) in each case, passing in either a HTTP or JSRPC backend (with common interface) to do the API call and marshalling. Let's perhaps leave that as a follow-up, though...
| } | ||
|
|
||
| export const test = { | ||
| async test(ctrl, env, ctx) { |
There was a problem hiding this comment.
Ideally I'd like us to run the canonical R2 test suite (r2-test.js) on both the existing implementation and the JSRPC implementation so the full test suite is run on both backends and there is no duplication of test case logic.
I think this should be possible to achieve by teaching r2-test.js's fake backend to support both transports, then run the same test module twice with different compat flags (you'd need to add a second .wd-test config which sets the compat flag appropriately and points the binding's r2Bucket at a backend supporting the appropriate transport).
No description provided.